﻿// 存放一些可以复用的函数
#include "xplaneConnect.h"
#include"dataThread.h"
#include "skyThread.h"

mouse_msg msg;
bool leftButtonDown = false;
BYTE alpha = 255;//透明度
double LV = 1.0;//亮度（0.0-1.0
PIMAGE bkpfd = newimage();

// 初始化窗口和图形
WindowParams initializeWindow() {
    // 禁用系统DPI缩放，获取物理分辨率
    SetProcessDpiAwarenessContext(DPI_AWARENESS_CONTEXT_SYSTEM_AWARE);
    setcaption("Airbus A350 XWB");

    WindowParams params;
    params.width = GetSystemMetrics(SM_CXSCREEN);
    params.height = GetSystemMetrics(SM_CYSCREEN);

    //params.base_width = 1.5f * params.width / 4.0f;
    params.base_width = -1.0f;
    //params.base_height = 3.0f * params.height / 4.0f;
    params.base_height = -1.0f;
    initgraph(static_cast<int>(params.base_width), static_cast<int>(params.base_height), INIT_NOFORCEEXIT | INIT_NOBORDER);
    //setbkcolor(EGEARGB(255, 38, 50, 64));

    return params;
}

// 处理鼠标输入
void handleMouseInput(ViewState& state, const WindowParams& window) {
    msg;
    const float ZOOM_SENSITIVITY = 0.0008f;

    while (mousemsg()) {
        msg = getmouse();
        if (msg.is_left()) {
            leftButtonDown = msg.is_down() ? true : false;
        }
        if (msg.is_wheel()) {
            int mouseX = msg.x;
            int mouseY = msg.y;

            // 计算世界坐标
            float worldX = (mouseX + state.offsetX) / state.scale;
            float worldY = (mouseY + state.offsetY) / state.scale;

            // 更新目标缩放
            state.targetScale = std::clamp(
                state.targetScale + msg.wheel * ZOOM_SENSITIVITY,
                0.8f,
                3.0f
            );

            // 计算新偏移
            state.targetOffsetX = worldX * state.targetScale - mouseX;
            state.targetOffsetY = worldY * state.targetScale - mouseY;
        }
    }
}

// 处理键盘输入
void handleKeyboardInput(ViewState& state, float deltaTime) {
    const float ACCELERATION = 800.0f;
    const float MAX_SPEED = 1000.0f;

    if (keystate(VK_LEFT)) state.velocityX -= ACCELERATION * deltaTime;
    if (keystate(VK_RIGHT)) state.velocityX += ACCELERATION * deltaTime;
    if (keystate(VK_UP)) state.velocityY -= ACCELERATION * deltaTime;
    if (keystate(VK_DOWN)) state.velocityY += ACCELERATION * deltaTime;
    if (keystate(0x6b) && LV + 0.01 <= 1) {
        LV += 0.01;
    }//调节亮度     
    if (keystate(0x6d) && LV - 0.01 >= 0) {
        LV -= 0.01;
    }//调节亮度     
    // 限制速度
    state.velocityX = std::clamp(state.velocityX, -MAX_SPEED, MAX_SPEED);
    state.velocityY = std::clamp(state.velocityY, -MAX_SPEED, MAX_SPEED);
}

 void reverseTransmission(float flap,float gear1)
{
    double pitch=0, roll=0, direction=0;
    const char* drefsPitch[] = { "sim/cockpit2/controls/yoke_pitch_ratio"};//AirbusFBW/NDmodeCapt//sim/cockpit2/controls/yoke_heading_ratio
    const char* drefsDirection[] = { "sim/cockpit2/controls/yoke_heading_ratio"};
    const char* drefsRoll[] = { "sim/cockpit2/controls/yoke_roll_ratio" };
    const char* drefsButtonND[] = { "1-sim/fcu/ndModeLeft/switch" };
    const char* drefsFlap[] = { "sim/cockpit2/controls/flap_ratio" };
    const char* drefsgear1[] = { "sim/cockpit/switches/gear_handle_status" };
    float* valuesPitch[1];
    float* valuesHeading[1];
    float* valuesRoll[1];
    float* valuesButtonND[1];
    float* valuesFlap[1];
    float* valuesgear1[1];
        valuesPitch[0] = (float*)malloc(4);
        valuesHeading[0] = (float*)malloc(4);
        valuesRoll[0] = (float*)malloc(4);
        valuesButtonND[0] = (float*)malloc(4);
        valuesFlap[0] = (float*)malloc(4);
        valuesgear1[0] = (float*)malloc(4);

        int sizePitch = 1;
        int sizeDirection = 1;
        int sizeRoll = 1;
        int sizeButtonND = 1;
        int sizeFlap = 1;
        int sizegear1 = 1;


        valuesFlap[0][0] = flap;
        
    //int sizes[] = { 1, 1 };
    XPCSocket sock = openUDP(MYIP);
    //sendDREFs(sock, drefsButtonND, valuesButtonND, &sizeButtonND, 1);

    
    if (keystate(key_W))
    {
        if (pitch < 1)
        {
            pitch += 0.5;
        }
        valuesPitch[0][0] = 1;
        sendDREFs(sock, drefsPitch, valuesPitch, &sizePitch, 1);

    }
    if (keystate(key_S))
    {
        if (pitch > -1)
        {
            pitch -= 0.25;
        }
        valuesPitch[0][0] = -1;
        sendDREFs(sock, drefsPitch, valuesPitch, &sizePitch, 1);

    }
    if (keystate(key_A))
    {
        if (direction < 1)
        {
            direction += 0.5;
        }
        valuesHeading[0][0] = direction;
        sendDREFs(sock, drefsDirection, valuesHeading, &sizeDirection, 1);

    }
    if (keystate(key_D))
    {
        if (direction > -1)
        {
            direction -= 0.5;
        }
        valuesHeading[0][0] = direction;
        sendDREFs(sock, drefsDirection, valuesHeading, &sizeDirection, 1);

    }
    if (keystate(key_Q))
    {
        if (roll < 1)
        {
            roll += 0.5;
        }
        valuesRoll[0][0] = roll;
        sendDREFs(sock, drefsRoll, valuesRoll, &sizeRoll, 1);

    }
    if (keystate(key_E))
    {
        if (roll > -1)
        {
            roll -= 0.5;
        }
        valuesRoll[0][0] = roll;
        sendDREFs(sock, drefsRoll, valuesRoll, &sizeRoll, 1);

    }
    if (keystate(key_num0))
    {
        
         valuesButtonND[0][0] = 0;
         sendDREFs(sock, drefsButtonND, valuesButtonND, &sizeButtonND, 1);
        
    }
    if (keystate(key_num1))
 
    {
        valuesButtonND[0][0] = 1;
        sendDREFs(sock, drefsButtonND, valuesButtonND, &sizeButtonND, 1);
    }
    if (keystate(key_num2))
    {
        valuesButtonND[0][0] = 2;
        sendDREFs(sock, drefsButtonND, valuesButtonND, &sizeButtonND, 1);
    }
    if (keystate(key_num3))
    {
        valuesButtonND[0][0] = 3;
        sendDREFs(sock, drefsButtonND, valuesButtonND, &sizeButtonND, 1);
    }
    if (keystate(key_num4))
    {
        valuesButtonND[0][0] = 4;
        sendDREFs(sock, drefsButtonND, valuesButtonND, &sizeButtonND, 1);
    }
    //收回襟翼
    if (keystate(key_1))
    {
        valuesFlap[0][0] -= 0.25;
        sendDREFs(sock, drefsFlap, valuesFlap, &sizeFlap, 1);
    }
    //释放襟翼
    if (keystate(key_2))
    {
        valuesFlap[0][0] += 0.25;
        sendDREFs(sock, drefsFlap, valuesFlap, &sizeFlap, 1);
    }
    //释放或收起起落架
    if (keystate(key_G))
    {
        if (gear1 == 0)
        {
            valuesFlap[0][0] = 1;
        }
        if (gear1 == 1)
        {
            valuesFlap[0][0] = 0;
        }
        sendDREFs(sock, drefsgear1, valuesgear1, &sizegear1, 1);
    }
    
}

// 更新运动状态
void updateMovement(ViewState& state, float deltaTime) {
    const float FRICTION = 1200.0f;
    const float SMOOTH_FACTOR = 5.0f;

    // 应用摩擦力
    auto applyFriction = [&](float& velocity, bool negKey, bool posKey) {
        if (!negKey && !posKey) {
            if (velocity > 0) velocity = max(velocity - FRICTION * deltaTime, 0.0f);
            else velocity = min(velocity + FRICTION * deltaTime, 0.0f);
        }
        };

    applyFriction(state.velocityX, keystate(VK_LEFT), keystate(VK_RIGHT));
    applyFriction(state.velocityY, keystate(VK_UP), keystate(VK_DOWN));

    // 更新目标偏移
    state.targetOffsetX += state.velocityX * deltaTime;
    state.targetOffsetY += state.velocityY * deltaTime;

    // 指数平滑插值
    float alpha = 1.0f - std::exp(-SMOOTH_FACTOR * deltaTime);
    state.scale += (state.targetScale - state.scale) * alpha;
    state.offsetX += (state.targetOffsetX - state.offsetX) * alpha;
    state.offsetY += (state.targetOffsetY - state.offsetY) * alpha;
}

// 计算视口参数
std::tuple<int, int, int> calculateViewportParams(
    const ViewState& state,
    float base_x,
    float base_y,
    float base_size,
    const WindowParams& window
) {
    float scaled_x = base_x * state.scale;
    float scaled_y = base_y * state.scale;
    float final_x_float = scaled_x - state.offsetX;
    float final_y_float = scaled_y - state.offsetY;
    float scaled_size = base_size * state.scale;

    int final_x = static_cast<int>(final_x_float + 0.5f);
    int final_y = static_cast<int>(final_y_float + 0.5f);
    int final_size = static_cast<int>(scaled_size + 0.5f);

    //if (final_x + final_size < 0 || final_x > window.base_width ||
    //    final_y + final_size < 0 || final_y > window.base_height) {
    //    return { -1, -1, 0 };
    //}
    return { final_x, final_y, final_size };
}
void drawbkPFD(int x0, int y0, double pfd_h)
{
    double pfd_w = pfd_h * 872 / 1123;

    resize(bkpfd , pfd_w * 2, pfd_w + pfd_h);
    setbkcolor(EGEARGB(0, 0, 0, 0), bkpfd);
    setfillcolor(EGEARGB(255, 0, 0, 0), bkpfd);
    ege_fillrect(0, 0, pfd_w / 2.0, pfd_w + pfd_h, bkpfd);
    ege_fillrect(0, 0, pfd_w * 2.0, pfd_w / 2.0, bkpfd);
    ege_fillrect(0, pfd_w / 2.0 + pfd_h, pfd_w * 2.0, pfd_w / 2.0, bkpfd);
    ege_fillrect(pfd_w * 3 / 2.0, 0, pfd_w / 2.0, pfd_w + pfd_h, bkpfd);
    setfillcolor(EGEARGB(0, 0, 0, 0), bkpfd);
    ege_fillrect(x0 - pfd_w / 2.0, x0 - pfd_w / 2.0, pfd_w, pfd_h, bkpfd);
    putimage_withalpha(NULL, bkpfd, x0 - pfd_w / 2.0, y0 - pfd_w / 2.0,0, 0, pfd_w * 2, pfd_w + pfd_h);

}